package com.rzgeo.rzmaplib.comp;

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.esri.arcgisruntime.arcgisservices.LabelDefinition;
import com.esri.arcgisruntime.data.Field;
import com.esri.arcgisruntime.geometry.GeometryType;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.layers.Layer;
import com.esri.arcgisruntime.loadable.LoadStatus;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.LayerViewStateChangedEvent;
import com.esri.arcgisruntime.mapping.view.LayerViewStateChangedListener;
import com.esri.arcgisruntime.mapping.view.LayerViewStatus;
import com.esri.arcgisruntime.symbology.Renderer;
import com.rzgeo.rzmaplib.R;
import com.rzgeo.rzmaplib.comp.geoview.IRmlGeoViewHolder;
import com.rzgeo.rzmaplib.model.RmlPrj;
import com.rzgeo.rzmaplib.util.RmlUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.widget.AbsListView.CHOICE_MODE_NONE;

/**
 * Created by Administrator on 2017/9/30.
 */

public class RmlLayerList extends RelativeLayout {

    private LabelHelper _labelHelper = new LabelHelper();

    private LayerAdapter _adapt;
    private Activity _activity;

    public enum LayerType {
        graphicOverLayer, FeatureLayer, FeatureLayerWithPolygon, OtherLayer
    }

    private IRmlGeoViewHolder _geoViewHolder;
    private ListView _layerListView;


    private Layer[] _ignoreLayers;
    private Map<GraphicsOverlay, String> _glTitles;

    public RmlLayerList(Context context) {
        super(context);
    }


    public RmlLayerList(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RmlLayerList(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    private RmlPrj.SymbolStack _symbolStack;

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        _symbolStack=new RmlPrj.SymbolStack(getContext());
        _layerListView = findViewById(R.id.listView);
        _layerListView.setChoiceMode(CHOICE_MODE_NONE);

        _adapt = new LayerAdapter(LayoutInflater.from(getContext()));
        _layerListView.setAdapter(_adapt);
    }


//    public interface onCompStateChanged{
//        void onHide();
//    }

//    public void setOnCompStateChanged(onCompStateChanged l){
//        _onCompStateChanged=l;
//    }

    public void setMapModel(Activity activity, IRmlGeoViewHolder mv, Layer[] ignoreLayers, Map<GraphicsOverlay, String> glTitles) {
        _ignoreLayers = ignoreLayers;
        _glTitles = glTitles;

        _geoViewHolder = mv;


        _activity = activity;
        if (_geoViewHolder != null) {
            this.setEnabled(true);
            if (_layerListView != null) {
                _geoViewHolder.getGeoView().addLayerViewStateChangedListener(new LayerViewStateChangedListener() {
                    @Override
                    public void layerViewStateChanged(LayerViewStateChangedEvent layerViewStateChangedEvent) {
                        if (layerViewStateChangedEvent.getLayerViewStatus().contains(LayerViewStatus.ACTIVE))
                            layerViewStateChangedEvent.getLayer();
                    }
                });
                _adapt.update(_geoViewHolder);
            }
        }


    }

    public class LayerHolder {
        public String Title;
        public Layer layer;
        public GraphicsOverlay graphicsOverlay;
        public Renderer defaultRendener;

        public LayerHolder(Layer l) {
            Title = l.getName();
            layer = l;
        }

        public LayerHolder(GraphicsOverlay gl) {
            if (_glTitles != null && _glTitles.containsKey(gl))
                Title = _glTitles.get(gl);
            else
                Title = "图层";

            graphicsOverlay = gl;
        }

        public LayerType getLayerType() {
            if (graphicsOverlay != null) {
                return LayerType.graphicOverLayer;
            } else {
                if (layer instanceof FeatureLayer) {
                    FeatureLayer fl = (FeatureLayer) layer;
                    if (fl.getFeatureTable().getGeometryType() == GeometryType.ENVELOPE
                            || fl.getFeatureTable().getGeometryType() == GeometryType.POLYGON)
                        return LayerType.FeatureLayerWithPolygon;
                    else
                        return LayerType.FeatureLayer;
                } else {
                    return LayerType.OtherLayer;
                }
            }
        }
    }

    private class LayerAdapter extends BaseAdapter {
        private LayoutInflater _inflater;
        private ArrayList<LayerHolder> _layers;

        public LayerAdapter(LayoutInflater inflater) {
            _inflater = inflater;
            _layers = new ArrayList<>(12);
        }

        public void update(IRmlGeoViewHolder gv) {
            _layers.clear();

            for (Layer l : gv.getBaseLayers()) {
                _layers.add(new LayerHolder(l));
            }

            for (final Layer l : gv.getRefrenceLayers()) {
                _layers.add(new LayerHolder(l));
                trySetFeatureLayerState(l);
            }

            for (Layer l : gv.getOperationalLayers()) {
                _layers.add(new LayerHolder(l));
                trySetFeatureLayerState(l);
            }

            notifyDataSetChanged();
        }

        private void trySetFeatureLayerState(Layer l){
            if(l instanceof FeatureLayer){
                final FeatureLayer fl= (FeatureLayer) l;
                if(fl.getLoadStatus()== LoadStatus.LOADED){
                    setFeatureLayerState(fl);
                }else{
                    l.addDoneLoadingListener(new Runnable() {
                        @Override
                        public void run() {
                            if(fl.getLoadStatus()== LoadStatus.LOADED)
                                setFeatureLayerState(fl);
                        }
                    });
                }
            }
        }




        private void setFeatureLayerState(FeatureLayer l){

//            Renderer.fromJson();
            Renderer r = _symbolStack.getRenderer(l.getFeatureTable().getGeometryType());

            if (r != null) {
                l.setRenderer(r);
            }
//            l.getLabelDefinitions()
            LabelHelper.LabelInfo infos = _labelHelper.getLabelDefTitle(l);

            for(int i=0;i<infos.labelDefinitions.length;i++){
                if(infos.titles[i].equalsIgnoreCase("lable")){
                    List<LabelDefinition> ldefs = l.getLabelDefinitions();
                    ldefs.clear();
                    ldefs.addAll(infos.labelDefinitions[i]);
//                    l.setLabelsEnabled(true);
                    break;
                }
            }
        }

        public void setVisibleForAll(boolean visible) {
            for (LayerHolder lh : _layers) {
                switch (lh.getLayerType()) {
                    case graphicOverLayer:
                        lh.graphicsOverlay.setVisible(visible);
                        break;
                    default:
                        if (lh.layer != null)
                            lh.layer.setVisible(visible);
                }
            }
            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return _layers.size();
        }

        @Override
        public Object getItem(int position) {
            return _layers.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = _inflater.inflate(R.layout.comp_layer_list_item, null);
            }
            RmlLayerListItem ItemView = (RmlLayerListItem) convertView;
            ItemView.setup(_layers.get(position), RmlLayerList.this);
            return convertView;
        }
    }

    private static class LabelHelper {

        public static class LabelInfo {
            public String[] titles;
            public int selectIndex;
            public List<LabelDefinition>[] labelDefinitions;
        }

        public Map<FeatureLayer, LabelInfo> layer2LabelInfo =
                new HashMap<>();

        public static LabelDefinition createFieldLabel(String field) {

            String fontName = RmlUtil.Font.Default;
            String symbol =
                    "{" +
                            "\"angle\": 0," +
                            "\"backgroundColor\": [0, 0, 0, 0]," +
                            "\"borderLineColor\": [0, 0, 0, 0]," +
                            "\"borderLineSize\": 0," +
                            "\"color\": [197, 0, 255, 255]," +
                            "\"font\": {" +
                            "\"decoration\": \"none\"," +
                            "\"family\": \"" + fontName + "\"," +
                            "\"size\": 10," +
                            "\"style\": \"normal\"," +
                            "\"weight\": \"normal\"" +
                            "}," +

                            "\"haloColor\": [0, 0, 0, 0]," +
                            "\"haloSize\": 0," +
                            "\"horizontalAlignment\": \"center\"," +
                            "\"kerning\": true," +
                            "\"type\": \"esriTS\"," +
                            "\"verticalAlignment\": \"bottom\"," +
                            "\"xoffset\": 0," +
                            "\"yoffset\": 0," +
                            "\"rightToLeft\": false" +
                            "}";

            String labelJson =
                    "{" +
                            "\"labelExpression\": \"[" + field + "]\"," +
                            "\"labelPlacement\": \"esriServerPolygonPlacementAlwaysHorizontal\"," +
                            "\"maxScale\": 0," +
                            "\"minScale\": 0," +
                            "\"useCodedValues\": true," +
                            "\"symbol\":" + symbol  +
                            "}";

            return LabelDefinition.fromJson(labelJson);
        }

        public LabelInfo getLabelDefTitle(FeatureLayer layer) {
            LabelInfo labelInfo = layer2LabelInfo.get(layer);

            if (labelInfo == null) {
                labelInfo = new LabelInfo();

                List<Field> fields = layer.getFeatureTable().getFields();
                String[] fieldNames = new String[fields.size() + 1];
                fieldNames[0] = "默认";

                labelInfo.titles = fieldNames;
                labelInfo.selectIndex = 0;
                labelInfo.labelDefinitions = new List[fields.size() + 1];
                labelInfo.labelDefinitions[0] = layer.getLabelDefinitions();

                for (int i = 1; i < fieldNames.length; i++) {
                    Field f = fields.get(i-1);
                    fieldNames[i ] = f.getName();
                    ArrayList<LabelDefinition> defs = new ArrayList<>();
                    defs.add(createFieldLabel(f.getName()));
                    labelInfo.labelDefinitions[i ] = defs;
                }
            }

            return labelInfo;
        }
    }
}
